/*
    SUSAN® - Sole of Unix Save ANything

   

   

   

   
*/

#ifndef BAREOS_SRC_TESTS_SCHEDULER_TIME_SOURCE_H_
#define BAREOS_SRC_TESTS_SCHEDULER_TIME_SOURCE_H_

#include "dird/scheduler.h"
#include "dird/scheduler_time_adapter.h"

#include <atomic>
#include <condition_variable>
#include <thread>
#include <iomanip>
#include <iostream>
#include <vector>

static bool debug{false};

/* libstdc++ on rhel7 does not have put_time, so we add it here */
std::string put_time(const std::tm* tmb, const char* fmt)
{
  size_t maxlen = strlen(fmt) + 100;
  std::vector<char> s(maxlen);
  strftime(s.data(), s.size(), fmt, tmb);
  return std::string{s.data()};
}

class SimulatedTimeSource : public directordaemon::TimeSource {
 public:
  SimulatedTimeSource()
  {
    running_ = true;
    clock_value_ = 959817600;  // UTC: 01-06-2000 00:00:00

    if (debug) {
      time_t t{clock_value_};
      std::cout << put_time(
                       gmtime(&t),
                       "Start simulated Clock at time: %A %d-%m-%Y %H:%M:%S")
                << std::endl;
    }
  }

  ~SimulatedTimeSource() { Terminate(); }

  void SleepFor(std::chrono::seconds wait_interval_pseudo_seconds) override
  {
    time_t wait_until_ =
        clock_value_ +
        static_cast<time_t>(wait_interval_pseudo_seconds.count());
    while (running_ && clock_value_ < wait_until_) { clock_value_ += 1; }
  }

  void Terminate() override { running_ = false; }
  time_t SystemTime() override { return clock_value_; }
  static void ExecuteJob(JobControlRecord* jcr);

 private:
  std::atomic<bool> running_;
  std::atomic<time_t> clock_value_;
};

#endif  // BAREOS_SRC_TESTS_SCHEDULER_TIME_SOURCE_H_
